package com.rongke.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.rongke.alipayUtil.alipay.util.AlipayRefundUtil;
import com.rongke.enums.FlowTypeEnum;
import com.rongke.enums.OrderStatusEnum;
import com.rongke.enums.PayTypeEnum;
import com.rongke.enums.UserTypeEnum;
import com.rongke.mapper.BuyTogetherUserMapper;
import com.rongke.model.*;
import com.rongke.service.*;
import com.rongke.utils.OrderUtils;
import com.rongke.wxPayUtil.wxRefundUtil.wechat.RefundUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @BuyTogetherUserServiceImpl
 * @ServiceImpl
 * @version : Ver 1.0
 */
@Service
public class BuyTogetherUserServiceImpl extends ServiceImpl<BuyTogetherUserMapper, BuyTogetherUser> implements BuyTogetherUserService {

    @Autowired
    private BuyTogetherUserMapper buyTogetherUserMapper;
    @Autowired
    private BuyTogetherUserService buyTogetherUserService;
    @Autowired
    private BuyTogetherGoodsService buyTogetherGoodsService;
    @Autowired
    private OrderGoodsService orderGoodsService;
    @Autowired
    private OrdersService ordersService;
    @Autowired
    private MuserService muserService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private FlowDetailService flowDetailService;
    /**
     * @根据条件查找
     * @param buyTogetherUser
     * @return
     */
    @Override
    public List<BuyTogetherUser> selectByCondition(BuyTogetherUser buyTogetherUser) {
        return buyTogetherUserMapper.selectByCondition(buyTogetherUser);
    }

    @Override
    public List<BuyTogetherUser> selectBuyTogetherUser(Map map) {

        return buyTogetherUserMapper.selectBuyTogetherUser(map);
    }

    @Override
    public Integer selectBuyTogetherUserPageSize(Map map) {
        return buyTogetherUserMapper.selectBuyTogetherUserPageSize(map);
    }

    @Override
    public List<BuyTogetherUser> selectBuyTogetherUserPage(Map map) {
        return buyTogetherUserMapper.selectBuyTogetherUserPage(map);
    }

    @Override
    public JSONObject insertButogetherUserData(Long orderId, String buyTogetherCode) {
        JSONObject json=new JSONObject();
        Orders orders=ordersService.selectById(orderId);
        EntityWrapper<OrderGoods> ew2=new EntityWrapper<>();
        ew2.eq("order_id",orderId);
        OrderGoods orderGoods=orderGoodsService.selectOne(ew2);
        EntityWrapper<BuyTogetherGoods> ew3=new EntityWrapper<>();
        ew3.eq("goods_id",orderGoods.getGoodsId());
        BuyTogetherGoods btg=buyTogetherGoodsService.selectOne(ew3);
        Integer needNum=btg.getNeedTogetherNum();
        BuyTogetherUser btu=new BuyTogetherUser();
        if(buyTogetherCode==null){//说明该订单为开团人所下单
            btu.setMuserId(orders.getMuserId());
            btu.setBtgId(btg.getId());
            btu.setBuyTogetherTime(new Date());
            btu.setSkuId(orderGoods.getSkuId());
            btu.setNowTogetherNum(1);
            btu.setHead(true);
            buyTogetherCode=OrderUtils.butTogetherCode(6);
            btu.setBuyTogetherCode(buyTogetherCode);
            btu.setActivityOn(true);
            btu.setStatus(1);
            buyTogetherUserService.insert(btu);

        }else {//根据开团号查出该商品所有拼团人 更新已拼团人数
            EntityWrapper<BuyTogetherUser> ew=new EntityWrapper<>();
            ew.eq("buy_together_code",buyTogetherCode);
            Lock lock=new ReentrantLock();
            try {
                lock.lock();
                List<BuyTogetherUser> buyTogetherUserList=buyTogetherUserMapper.selectList(ew);
                BuyTogetherUser one=buyTogetherUserList.get(0);
                if(one.getNowTogetherNum()>needNum){
                    json.put("code","500");
                    json.put("message","拼团人数已满");
                    return json;
                }
                for (BuyTogetherUser bt:buyTogetherUserList ) {
                    bt.setNowTogetherNum(bt.getNowTogetherNum()+1);
                }
                btu.setMuserId(orders.getMuserId());
                btu.setBtgId(btg.getId());
                btu.setBuyTogetherTime(new Date());
                btu.setSkuId(orderGoods.getSkuId());
                btu.setNowTogetherNum(one.getNowTogetherNum());
                btu.setBuyTogetherCode(buyTogetherCode);
                btu.setHead(false);
                btu.setActivityOn(true);
                btu.setStatus(1);
                buyTogetherUserList.add(btu);
                buyTogetherUserService.insertOrUpdateAllColumnBatch(buyTogetherUserList);
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }

        }
        orders.setBuyTogetherCode(buyTogetherCode);
        ordersService.updateById(orders);
        json.put("code","200");
        return json;

    }

    @Override
    public List<BuyTogetherUser> selectTogetherUserAndTogetherGoodsList(Map map) {
        return buyTogetherUserMapper.selectTogetherUserAndTogetherGoodsList(map);
    }


    @Override
    public void buyTogetherTask() {
        Map map=new HashMap();
        map.put("isActivityOn",1);
        map.put("isHead",1);
        List<BuyTogetherUser> btuList=buyTogetherUserService.selectTogetherUserAndTogetherGoodsList(map);
        if(btuList.isEmpty()){
            return;
        }
        for (int i=0,y=btuList.size();i<y;i++){
            BuyTogetherUser btu=btuList.get(i);
            int neesNum=btu.getBtg().getNeedTogetherNum();
            Date startTime=btu.getBuyTogetherTime();
            Long leftTime = startTime.getTime()+btu.getBtg().getBuyTogetherLimitTime()*60*60*1000-new Date().getTime();
            EntityWrapper<BuyTogetherUser> ew=new EntityWrapper<>();
            ew.eq("buy_together_code",btu.getBuyTogetherCode());
            List<BuyTogetherUser> buyTogetherUsers=buyTogetherUserService.selectList(ew);
            EntityWrapper<Orders> ew2=new EntityWrapper<>();
            ew2.eq("buy_together_code",btu.getBuyTogetherCode());
            List<Orders> orderList=ordersService.selectList(ew2);
            int status=2;//默认拼团成功
            if(leftTime<=0){
                if(neesNum>buyTogetherUsers.size()){//人数不够
                    for (Orders order:orderList ) {
                        order.setOrderStatus(OrderStatusEnum.REFUNDED.getType());
                    }
                    ordersService.updateBatchById(orderList);
                    status=3;//拼团失败
                    //退款操作。。。。
                    refund(orderList);
                }else {
                    for (Orders order:orderList ) {
                        order.setOrderStatus(OrderStatusEnum.WAIT_SHIP.getType());
                    }
                    ordersService.updateBatchById(orderList);
                }
                for (BuyTogetherUser bt:buyTogetherUsers ) {
                    bt.setActivityOn(false);
                    bt.setStatus(status);
                }
                buyTogetherUserService.updateBatchById(buyTogetherUsers);

            }else {
                //如果时间没到人数已够 拼团结束
                if(neesNum==buyTogetherUsers.size()){
                    for (Orders order:orderList ) {
                        order.setOrderStatus(OrderStatusEnum.WAIT_SHIP.getType());
                    }
                    ordersService.updateBatchById(orderList);
                    for (BuyTogetherUser bt:buyTogetherUsers ) {
                        bt.setActivityOn(false);
                        bt.setStatus(status);
                    }
                    buyTogetherUserService.updateBatchById(buyTogetherUsers);
                }

            }
        }
    }

    /**
     * 拼团退款
     * @param ordersList
     * @return
     */
    public JSONObject  refund(List<Orders> ordersList){
        JSONObject json=new JSONObject();
        for(int i=0,y=ordersList.size();i<y;i++){
            Orders orders=ordersList.get(i);
            String outTradeNo=orders.getOutTradeNo();
            EntityWrapper<Account> ewAcc=new EntityWrapper<>();
            ewAcc.eq("muser_id",orders.getMuserId());
            Account account=accountService.selectOne(ewAcc);
            if(orders.getPayType()== PayTypeEnum.WEIXIN.getType()){
                ClassLoader classLoader=getClass().getClassLoader();
                URL url = classLoader.getResource("apiclient_cert.p12");
                String path=url.getFile();
                String refund_fee=new BigDecimal(100).multiply(orders.getCashPayPrice()).setScale(0,BigDecimal.ROUND_HALF_UP).toString();
                Map<String, String> refundMap= RefundUtil.wechatRefund(outTradeNo,refund_fee,refund_fee,path);
                if(refundMap.containsKey("err_code")){
                    json.put("message",refundMap.get("err_code_des"));
                    return json;
                }else if("FAIL".equals(refundMap.get("return_code"))){
                    json.put("message",refundMap.get("return_msg"));
                    return json;
                }
                /******************退款记录*************************/
                FlowDetail fd=new FlowDetail();
                fd.setMuserId(orders.getMuserId());
                fd.setMoney(orders.getCashPayPrice());
                fd.setFlowType(FlowTypeEnum.FEFUNDDUOBI.getType());
                fd.setTitle("拼团失败微信退款金额"+orders.getCashPayPrice());
                fd.setGmtDatetime(new Date());
                fd.setOrderNumber(orders.getOrderNumber());
                fd.setPayType(PayTypeEnum.WEIXIN.getType());
                flowDetailService.insert(fd);
                if(orders.getCashPayPrice().compareTo(orders.getTotalPrice())<0){
                    Integer allowPayType=orders.getAllowPayType();
                    FlowDetail yue=new FlowDetail();
                    yue.setMuserId(orders.getMuserId());
                    yue.setMoney(orders.getTotalPrice().subtract(orders.getCashPayPrice()));
                    yue.setFlowType(FlowTypeEnum.FEFUNDDUOBI.getType());
                    yue.setOrderNumber(orders.getOrderNumber());
                    yue.setPayType(PayTypeEnum.WEIXIN.getType());
                    BigDecimal leftMoney=orders.getTotalPrice().subtract(orders.getCashPayPrice());
                    if(allowPayType==1){
                        account.setDuoBi(account.getDuoBi().add(leftMoney));
                        yue.setTitle("拼团失败退款哆币金额"+leftMoney);
                    }else if(allowPayType==2){
                        account.setYaBi(account.getYaBi().add(leftMoney));
                        yue.setTitle("拼团失败退款雅币金额"+leftMoney);
                    }
                    yue.setGmtDatetime(new Date());
                    flowDetailService.insert(fd);
                }
            }else if(orders.getPayType()== PayTypeEnum.ZHIFUBAO.getType()){
                String strResponse=  AlipayRefundUtil.alipayRefundRequest(outTradeNo,"",orders.getCashPayPrice().doubleValue());
                if(strResponse!=null){
                    json.put("message",strResponse);
                    return json;
                }
                /******************退款记录*************************/
                FlowDetail fd=new FlowDetail();
                fd.setMuserId(orders.getMuserId());
                fd.setMoney(orders.getCashPayPrice());
                fd.setFlowType(FlowTypeEnum.FEFUNDDUOBI.getType());
                fd.setTitle("拼团失败支付宝退款金额"+orders.getCashPayPrice());
                fd.setPayType(PayTypeEnum.ZHIFUBAO.getType());
                fd.setOrderNumber(orders.getOrderNumber());
                fd.setGmtDatetime(new Date());
                flowDetailService.insert(fd);
                BigDecimal leftMoney=orders.getTotalPrice().subtract(orders.getCashPayPrice());
                if(orders.getCashPayPrice().compareTo(orders.getTotalPrice())<0){
                    FlowDetail yue=new FlowDetail();
                    yue.setMuserId(orders.getMuserId());
                    yue.setMoney(orders.getTotalPrice().subtract(orders.getCashPayPrice()));
                    yue.setFlowType(FlowTypeEnum.FEFUNDDUOBI.getType());
                    yue.setOrderNumber(orders.getOrderNumber());
                    yue.setPayType(PayTypeEnum.ZHIFUBAO.getType());
                    if(orders.getAllowPayType()==1){
                        account.setDuoBi(account.getDuoBi().add(leftMoney));
                        yue.setTitle("拼团失败退款哆币金额"+leftMoney);
                    }else if(orders.getAllowPayType()==2){
                        account.setYaBi(account.getYaBi().add(leftMoney));
                        yue.setTitle("拼团失败退款雅币金额"+leftMoney);
                    }
                    yue.setGmtDatetime(new Date());
                    flowDetailService.insert(fd);
                }
            }else{
                if(orders.getPayType()== PayTypeEnum.DUOBI.getType()) {
                    account.setDuoBi(account.getDuoBi().add(orders.getTotalPrice()));
                }else if(orders.getPayType()== PayTypeEnum.YABI.getType()){
                    account.setYaBi(account.getYaBi().add(orders.getTotalPrice()));
                }
                accountService.updateById(account);
                /******************退款记录*************************/
                FlowDetail fd=new FlowDetail();
                fd.setMuserId(orders.getMuserId());
                fd.setMoney(orders.getTotalPrice());
                fd.setOrderNumber(orders.getOrderNumber());
                if(orders.getPayType()== PayTypeEnum.DUOBI.getType()) {
                    fd.setFlowType(FlowTypeEnum.FEFUNDDUOBI.getType());
                    fd.setTitle("拼团失败退还哆币金额"+orders.getTotalPrice());
                    fd.setPayType(PayTypeEnum.DUOBI.getType());
                }else if(orders.getPayType()== PayTypeEnum.YABI.getType()){
                    fd.setFlowType(FlowTypeEnum.FEFUNDYABI.getType());
                    fd.setTitle("拼团失败退还雅币金额"+orders.getTotalPrice());
                    fd.setPayType(PayTypeEnum.YABI.getType());
                }
                fd.setGmtDatetime(new Date());
                flowDetailService.insert(fd);
            }

            //**************推荐人不可用余额减掉****************//
            Muser recomendMuser = muserService.findFirstRecomendUser(orders.getMuserId(), UserTypeEnum.CENTURION.getType());
            if (recomendMuser != null) {
                JSONObject jsonRecomend = accountService.updateRecomendUserAccount(recomendMuser.getId(), orders.getId());
                json.put("code","500");
                json.put("message",jsonRecomend.getString("message"));
            }
            // 获取购买人推荐人关系链，如果关系链上面有一个或多个推荐人为千夫长，则第一个千夫长不可用余额增加
            Muser chiefCommander = muserService.findFirstRecomendUser(orders.getMuserId(), UserTypeEnum.ChIEFCOMMANDER.getType());
            if (chiefCommander != null) {
                JSONObject jsonChief = accountService.updateRecomendUserAccount(chiefCommander.getId(), orders.getId());
                json.put("code","500");
                json.put("message",jsonChief.getString("message"));

            }
            // 获取购买人推荐人关系链，如果关系链上面有一个或多个推荐人为加盟商，则第一个加盟商不可用余额增加
            Muser franchisee = muserService.findFirstRecomendUser(orders.getMuserId(), UserTypeEnum.FRANCHISEE.getType());
            if (franchisee != null) {
                JSONObject jsonChief = accountService.updateRecomendUserAccount(franchisee.getId(), orders.getId());
                json.put("code","500");
                json.put("message",jsonChief.getString("message"));
            }
        }

        json.put("code","200");
        return json;
    }



}







